/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { ModalRef } from '@iux/live';
import {
  BaseUtilService,
  ClientManagerApiService,
  DataMap,
  DataMapService,
  I18NService
} from 'app/shared';
import { CheckHostModificationParam } from 'app/shared/api/models';
import { assign, includes, trim } from 'lodash';
import { Observable } from 'rxjs';

@Component({
  selector: 'aui-check-update-agent',
  templateUrl: './check-update-agent.component.html',
  styleUrls: ['./check-update-agent.component.less']
})
export class CheckUpdateAgentComponent implements OnInit {
  agent;
  formGroup: FormGroup;
  dataMap = DataMap;

  isSshPort: boolean;
  portTips: string;
  showUserType: boolean;
  userTypeOptions = this.dataMapService.toArray('userType').filter(v => {
    return (v.isLeaf = true);
  });
  passwordTypeOptions = this.dataMapService
    .toArray('passwordType')
    .filter(v => {
      return (v.isLeaf = true);
    });
  thmsOptions = this.dataMapService
    .toArray('hmacSignatureAlgorithm')
    .filter(item => {
      return (item.isLeaf = true);
    });

  osTyeMap = {
    [DataMap.Os_Type.windows.value]: DataMap.OS_Type.Windows.value,
    [DataMap.Os_Type.linux.value]: DataMap.OS_Type.Linux.value,
    [DataMap.Os_Type.aix.value]: DataMap.OS_Type.Unix.value,
    [DataMap.Os_Type.hpux.value]: DataMap.OS_Type.hpux.value,
    [DataMap.Os_Type.solaris.value]: DataMap.OS_Type.solaris.value
  };

  portErrorTip = {
    ...this.baseUtilService.rangeErrorTip,
    invalidRang: this.i18n.get('common_valid_rang_label', [1, 65535])
  };
  usernameErrorTip = {
    ...this.baseUtilService.requiredErrorTip,
    invalidMaxLength: this.i18n.get('common_valid_maxlength_label', [255])
  };
  passwordErrorTip = {
    ...this.baseUtilService.requiredErrorTip,
    invalidMaxLength: this.i18n.get('common_valid_maxlength_label', [255])
  };

  constructor(
    private modal: ModalRef,
    private fb: FormBuilder,
    private i18n: I18NService,
    private dataMapService: DataMapService,
    private baseUtilService: BaseUtilService,
    private clientManagerApiService: ClientManagerApiService
  ) {}

  ngOnInit(): void {
    this.init();
  }

  checkSudoPassword(res) {
    if (res === DataMap.passwordType.no.value) {
      this.formGroup.get('sudoPassword')?.enable();
    } else {
      this.formGroup.get('sudoPassword')?.disable();
    }
  }

  listenForm() {
    this.formGroup
      .get('userType')
      ?.valueChanges.subscribe(() =>
        this.checkSudoPassword(this.formGroup.get('passwordType')?.value)
      );
    this.formGroup
      .get('passwordType')
      .valueChanges.subscribe(res => this.checkSudoPassword(res));
    this.formGroup.statusChanges.subscribe(() => {
      this.modal.getInstance().lvOkDisabled = this.formGroup.invalid;
    });
  }

  init() {
    this.isSshPort = includes(
      [
        DataMap.Os_Type.linux.value,
        DataMap.Os_Type.unix.value,
        DataMap.Os_Type.solaris.value
      ],
      this.agent?.osType
    );
    this.showUserType = includes(
      [DataMap.Os_Type.linux.value, DataMap.Os_Type.unix.value],
      this.agent?.osType
    );

    const portValid = [
      this.baseUtilService.VALID.required(),
      this.baseUtilService.VALID.integer(),
      this.baseUtilService.VALID.rangeValue(1, 65535)
    ];
    const commonLengthValid = [
      this.baseUtilService.VALID.required(),
      this.baseUtilService.VALID.maxLength(255)
    ];
    this.formGroup = this.fb.group({
      port: new FormControl(this.isSshPort ? '22' : '5985', {
        validators: portValid
      }),
      sftpPort: new FormControl(
        { value: '22', disabled: !this.isSshPort },
        {
          validators: portValid
        }
      ),
      userType: new FormControl(DataMap.userType.admin.value),
      passwordType: new FormControl(false),
      username: new FormControl('', {
        validators: commonLengthValid
      }),
      password: new FormControl('', {
        validators: commonLengthValid
      }),
      sudoPassword: new FormControl(
        { value: '', disabled: true },
        {
          validators: commonLengthValid
        }
      ),
      algorithms: new FormControl(
        {
          value: DataMap.hmacSignatureAlgorithm.safe.value,
          disabled: !this.isSshPort
        },
        {
          validators: [this.baseUtilService.VALID.required()]
        }
      )
    });

    this.listenForm();
  }

  onOK(): Observable<void> {
    const checkParams: CheckHostModificationParam = {
      osType: this.osTyeMap[this.agent?.osType] || this.agent?.osType,
      ipType: includes(this.agent?.endpoint, ':') ? 'IPV6' : 'IPV4',
      agentId: this.agent?.uuid,
      ip: this.agent?.endpoint,
      port: Number(this.formGroup.get('port')?.value),
      sftpPort: this.formGroup.get('sftpPort')?.value
        ? Number(this.formGroup.get('sftpPort')?.value)
        : 22,
      username: this.formGroup.get('username')?.value,
      password: this.formGroup.get('password')?.value
    };
    if (this.isSshPort) {
      assign(checkParams, {
        macs: this.formGroup.get('algorithms')?.value
      });
    }
    if (this.showUserType) {
      const userType = this.formGroup.get('userType')?.value;
      const passwordType = this.formGroup.get('passwordType')?.value;
      assign(checkParams, {
        isSuperUser: userType === DataMap.userType.admin.value,
        isSudoNoPassword: passwordType,
        superPassword:
          userType === DataMap.userType.common.value && !passwordType
            ? this.formGroup.get('sudoPassword')?.value
            : ''
      });
    }
    assign(checkParams, {
      installPath: trim(this.agent?.extendInfo?.install_path)
    });
    return this.clientManagerApiService.checkAgentModificationUsingPOST({
      params: checkParams
    });
  }
}
